//
// winter - Direct2D GUI framework.
// Copyright (C) 2009 Aleksandar Dezelin 
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef APPLICATION_H
#define APPLICATION_H

#pragma once
#include "application_host.h"
#include "form.h"
#include "intrusive_ptr.h"
#include "message_pump.h"
#include "singleton.h"
#include "winter_assert.h"
#include <deque>
#include <string>

namespace winter {

using namespace std;
using namespace winter::platform;
using namespace winter::services;

///
/// <summary>
///     Class application manages the GUI application's control flow
///     and main settings.
/// </summary>
///
class application {
public:
  ///
  /// <summary>
  ///     Returns the handle of the windows application instance.
  /// </summary>
  /// <returns>
  ///     Instance handle.
  /// </returns>
  ///
  HINSTANCE get_instance() const {
    application_host* app_host = singleton<application_host>::instance();
    WINTER_ASSERT(app_host);
    return app_host->get_instance();
  }

  ///
  /// <summary>
  ///     Returns the id of the thread which created the application instance.
  /// </summary>
  /// <returns>
  ///     Thread id.
  /// </returns>
  int get_thread_id() const {
    application_host* app_host = singleton<application_host>::instance();
    WINTER_ASSERT(app_host);
    return app_host->get_thread_id();
  }

  ///
  /// <summary>
  ///     Processes the application's command line and runs a message pump.
  /// </summary>
  /// <param name="command_line">
  ///     Application's command line.
  /// </param>
  /// <returns>
  ///     Application's message pump error code.
  /// </returns>
  ///
  int run(const std::wstring& command_line) {
    // dispatch messages for the current thread
    platform::message_pump pump;
    return pump.run();

    UNREFERENCED_PARAMETER(command_line);
  }

  ///
  /// <summary>
  ///     Adds new application form to the list of forms.
  /// </summary>
  /// <param name="form">
  ///     The form.
  /// </param>
  ///
  void add_form(form* form) {
    _forms.push_back(form);
  }

  ///
  /// <summary>
  ///     Returns the total number of present application forms.
  /// </summary>
  /// <returns>
  ///     Number of present application forms.
  /// </returns>
  ///
  size_t forms_count() const {
    return _forms.size();
  }

  ///
  /// <summary>
  ///     Removes and destroys the form at the specified index in the list.
  /// </summary>
  /// <param name="index">
  ///     List index of the form to be removed.
  /// </param>
  ///
  void remove_form(int index) {
    _forms.erase(_forms.begin() + index);
  }

private:
  deque<intrusive_ptr<form>> _forms;
};

}

#endif // APPLICATION_H
